using Microsoft.EntityFrameworkCore;
using Universal.Application.Contracts.Common;
using Universal.Application.Contracts.Dto.ArticleCategory;
using Universal.Application.Repositories;
using Universal.Domain.Entities.App;
using Universal.Domain.Repositories;

namespace Universal.Application.Services;

/// <summary>
/// 文章分类服务
/// </summary>
public class ArticleCategoryService : IArticleCategoryService
{
    private readonly IRepository<AppArticleCategory> _repository;
    private readonly IRepository<AppArticle> _articleRepository;

    public ArticleCategoryService(IRepository<AppArticleCategory> repository, IRepository<AppArticle> articleRepository)
    {
        _repository = repository;
        _articleRepository = articleRepository;
    }

    public async Task<ApiResponse<ArticleCategoryDto>> CreateAsync(CreateArticleCategoryDto dto)
    {
        // 参数验证
        if (dto == null)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "参数不能为空");
        }

        if (string.IsNullOrWhiteSpace(dto.ArticleCategoryName))
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "分类名称不能为空");
        }

        // 检查分类名称是否唯一
        var isUnique = await IsNameUniqueAsync(dto.ArticleCategoryName, dto.ParentId);
        if (!isUnique.Data)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(5001, "分类名称在同层级中必须唯一");
        }

        // 检查父分类是否存在
        if (dto.ParentId.HasValue)
        {
            var parent = await _repository.GetByIdAsync(dto.ParentId.Value);
            if (parent == null)
            {
                return ApiResponse<ArticleCategoryDto>.Failure(5002, "父分类不存在");
            }
        }

        var entity = new AppArticleCategory
        {
            ArticleCategoryName = dto.ArticleCategoryName,
            Description = dto.Description,
            Sort = dto.Sort,
            ParentId = dto.ParentId,
            IsActive = dto.IsActive
        };

        var result = await _repository.AddAsync(entity);
        var dtoResult = MapToDto(result);

        return ApiResponse<ArticleCategoryDto>.Success(dtoResult, "创建成功");
    }

    public async Task<ApiResponse<ArticleCategoryDto>> UpdateAsync(UpdateArticleCategoryDto dto)
    {
        // 参数验证
        if (dto == null)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "参数不能为空");
        }

        if (dto.Id == Guid.Empty)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "分类ID不能为空");
        }

        if (string.IsNullOrWhiteSpace(dto.ArticleCategoryName))
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "分类名称不能为空");
        }

        var entity = await _repository.GetByIdAsync(dto.Id);
        if (entity == null)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(5003, "分类不存在");
        }

        // 检查分类名称是否唯一
        var isUnique = await IsNameUniqueAsync(dto.ArticleCategoryName, dto.ParentId, dto.Id);
        if (!isUnique.Data)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(5001, "分类名称在同层级中必须唯一");
        }

        // 检查父分类是否存在且不能是自己
        if (dto.ParentId.HasValue)
        {
            if (dto.ParentId.Value == dto.Id)
            {
                return ApiResponse<ArticleCategoryDto>.Failure(5004, "父分类不能是自己");
            }

            var parent = await _repository.GetByIdAsync(dto.ParentId.Value);
            if (parent == null)
            {
                return ApiResponse<ArticleCategoryDto>.Failure(5002, "父分类不存在");
            }
        }

        entity.ArticleCategoryName = dto.ArticleCategoryName;
        entity.Description = dto.Description;
        entity.Sort = dto.Sort;
        entity.ParentId = dto.ParentId;
        entity.IsActive = dto.IsActive;
        entity.UpdatedAt = DateTime.UtcNow;

        await _repository.UpdateAsync(entity);
        var dtoResult = MapToDto(entity);

        return ApiResponse<ArticleCategoryDto>.Success(dtoResult, "更新成功");
    }

    public async Task<ApiResponse<bool>> DeleteAsync(Guid id)
    {
        // 参数验证
        if (id == Guid.Empty)
        {
            return ApiResponse<bool>.Failure(400, "分类ID不能为空");
        }

        var entity = await _repository.GetByIdAsync(id);
        if (entity == null)
        {
            return ApiResponse<bool>.Failure(5003, "分类不存在");
        }

        // 检查是否是顶级分类
        // 检查是否有子分类
        var children = await _repository.Query()
            .Where(x => x.ParentId == id)
            .ToListAsync();

        if (children.Any())
        {
            return ApiResponse<bool>.Failure(5005, "该分类下有子分类，无法删除");
        }


        // 检查是否有关联的文章
        var articles = await _articleRepository.Query()
            .Where(x => x.CategoryId == id)
            .ToListAsync();

        if (articles.Any())
        {
            return ApiResponse<bool>.Failure(5006, "该分类下有关联的文章，无法删除");
        }

        await _repository.DeleteAsync(entity);
        return ApiResponse<bool>.Success(true, "删除成功");
    }

    public async Task<ApiResponse<ArticleCategoryDto>> GetByIdAsync(Guid id)
    {
        // 参数验证
        if (id == Guid.Empty)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(400, "分类ID不能为空");
        }

#pragma warning disable CS8603 // 可能返回 null 引用。
        var entity = await _repository.GetByIdWithIncludesAsync(id, x => x.Parent, x => x.Children, x => x.Articles);
#pragma warning restore CS8603 // 可能返回 null 引用。
        if (entity == null)
        {
            return ApiResponse<ArticleCategoryDto>.Failure(5003, "分类不存在");
        }

        var dto = MapToDto(entity);
        return ApiResponse<ArticleCategoryDto>.Success(dto);
    }

    // 修改 GetTreeAsync 方法，添加 activeOnly 参数
    public async Task<ApiResponse<List<ArticleCategoryDto>>> GetTreeAsync(bool activeOnly = true)
    {
        var query = _repository.Query()
            .Include(x => x.Parent)
            .Include(x => x.Articles)
            .AsQueryable();
        
        // 只有当 activeOnly 为 true 时才过滤激活状态
        if (activeOnly)
        {
            query = query.Where(x => x.IsActive);
        }
        
        var allCategories = await query
            .OrderBy(x => x.Sort)
            .ThenBy(x => x.CreatedAt)
            .ToListAsync();

        var rootCategories = allCategories.Where(x => !x.ParentId.HasValue).ToList();
        var tree = rootCategories.Select(category => BuildTree(category, allCategories)).ToList();

        return ApiResponse<List<ArticleCategoryDto>>.Success(tree);
    }

    public async Task<ApiResponse<PagedResult<ArticleCategoryDto>>> GetPagedAsync(ArticleCategoryQueryDto query)
    {
        // 参数验证
        if (query == null)
        {
            return ApiResponse<PagedResult<ArticleCategoryDto>>.Failure(400, "查询参数不能为空");
        }

        if (query.PageIndex < 1)
        {
            query.PageIndex = 1;
        }

        if (query.PageSize < 1 || query.PageSize > 100)
        {
            query.PageSize = 10;
        }

        var queryable = _repository.Query()
            .Include(x => x.Parent)
            .Include(x => x.Articles)
            .AsQueryable();

        // 关键字搜索
        if (!string.IsNullOrWhiteSpace(query.Keyword))
        {
            queryable = queryable.Where(x => x.ArticleCategoryName.Contains(query.Keyword) ||
                                           (x.Description != null && x.Description.Contains(query.Keyword)));
        }

        // 父分类筛选
        if (query.ParentId.HasValue)
        {
            queryable = queryable.Where(x => x.ParentId == query.ParentId.Value);
        }
        else if (query.ParentId == Guid.Empty) // 查询顶级分类
        {
            queryable = queryable.Where(x => !x.ParentId.HasValue);
        }

        // 激活状态筛选
        if (query.IsActive.HasValue)
        {
            queryable = queryable.Where(x => x.IsActive == query.IsActive.Value);
        }

        // 排序
        queryable = queryable.OrderBy(x => x.Sort).ThenBy(x => x.CreatedAt);

        var total = await queryable.CountAsync();
        var items = await queryable
            .Skip((query.PageIndex - 1) * query.PageSize)
            .Take(query.PageSize)
            .ToListAsync();

        var dtos = items.Select(MapToDto).ToList();
        var result = new PagedResult<ArticleCategoryDto>
        {
            TotalCount = total,
            TotalPages = (int)Math.Ceiling((double)total / query.PageSize),
            PageIndex = query.PageIndex,
            PageSize = query.PageSize,
            Items = dtos
        };

        return ApiResponse<PagedResult<ArticleCategoryDto>>.Success(result);
    }

    public async Task<ApiResponse<List<ArticleCategoryDto>>> GetChildrenAsync(Guid? parentId)
    {
        var children = await _repository.Query()
            .Include(x => x.Parent)
            .Include(x => x.Articles)
            .Where(x => x.ParentId == parentId && x.IsActive)
            .OrderBy(x => x.Sort)
            .ThenBy(x => x.CreatedAt)
            .ToListAsync();

        var dtos = children.Select(MapToDto).ToList();
        return ApiResponse<List<ArticleCategoryDto>>.Success(dtos);
    }

    public async Task<ApiResponse<bool>> ToggleActiveAsync(Guid id)
    {
        // 参数验证
        if (id == Guid.Empty)
        {
            return ApiResponse<bool>.Failure(400, "分类ID不能为空");
        }

        var entity = await _repository.GetByIdAsync(id);
        if (entity == null)
        {
            return ApiResponse<bool>.Failure(5003, "分类不存在");
        }

        entity.IsActive = !entity.IsActive;
        entity.UpdatedAt = DateTime.UtcNow;
        await _repository.UpdateAsync(entity);

        return ApiResponse<bool>.Success(true, entity.IsActive ? "已激活" : "已停用");
    }

    public async Task<ApiResponse<bool>> IsNameUniqueAsync(string name, Guid? parentId, Guid? excludeId = null)
    {
        // 参数验证
        if (string.IsNullOrWhiteSpace(name))
        {
            return ApiResponse<bool>.Failure(400, "分类名称不能为空");
        }

        var query = _repository.Query().Where(x => x.ArticleCategoryName == name && x.ParentId == parentId);

        if (excludeId.HasValue)
        {
            query = query.Where(x => x.Id != excludeId.Value);
        }

        var exists = await query.AnyAsync();
        return ApiResponse<bool>.Success(!exists);
    }

    /// <summary>
    /// 分配子分类
    /// </summary>
    public async Task<dynamic> AssignChildrenAsync(AssignChildrenDto assignChildrenDto)
    {
        // 参数验证
        if (assignChildrenDto == null)
        {
            return ApiResponse<string>.Failure(400, "参数不能为空");
        }

        if (assignChildrenDto.CategoryId == Guid.Empty)
        {
            return ApiResponse<string>.Failure(400, "分类ID不能为空");
        }

        if (assignChildrenDto.ChildCategoryIds == null || !assignChildrenDto.ChildCategoryIds.Any())
        {
            return ApiResponse<string>.Failure(400, "子分类ID不能为空");
        }

        var category = await _repository.GetByIdAsync(assignChildrenDto.CategoryId);

        if (category == null)
        {
            return ApiResponse<string>.Failure(5001, "分类不存在");
        }

        // 检查子分类是否存在
        foreach (var childCategoryId in assignChildrenDto.ChildCategoryIds)
        {
            var childCategory = await _repository.GetByIdAsync(childCategoryId);
            if (childCategory == null)
            {
                return ApiResponse<string>.Failure(5003, "子分类不存在");
            }
            category.AssignChild(childCategory);
        }

        await _repository.UpdateAsync(category);
        return ApiResponse<string>.Success("分配子分类成功");
    }

    /// <summary>
    /// 移除子分类
    /// </summary>
    public async Task<dynamic> RemoveChildrenAsync(AssignChildrenDto assignChildrenDto)
    {
        // 参数验证
        if (assignChildrenDto == null)
        {
            return ApiResponse<string>.Failure(400, "参数不能为空");
        }

        if (assignChildrenDto.CategoryId == Guid.Empty)
        {
            return ApiResponse<string>.Failure(400, "分类ID不能为空");
        }

        if (assignChildrenDto.ChildCategoryIds == null || !assignChildrenDto.ChildCategoryIds.Any())
        {
            return ApiResponse<string>.Failure(400, "子分类ID不能为空");
        }

        var category = await _repository.GetByIdAsync(assignChildrenDto.CategoryId);

        if (category == null)
        {
            return ApiResponse<string>.Failure(5001, "分类不存在");
        }

        // 移除子分类
        foreach (var childCategoryId in assignChildrenDto.ChildCategoryIds)
        {
            var childCategory = await _repository.GetByIdAsync(childCategoryId);
            if (childCategory != null && childCategory.ParentId == assignChildrenDto.CategoryId)
            {
                category.RemoveChild(childCategory);
            }
        }

        await _repository.UpdateAsync(category);
        return ApiResponse<string>.Success("移除子分类成功");
    }

    /// <summary>
    /// 分配文章到分类
    /// </summary>
    public async Task<dynamic> AssignArticlesAsync(AssignArticlesDto assignArticlesDto)
    {
        // 参数验证
        if (assignArticlesDto == null)
        {
            return ApiResponse<string>.Failure(400, "参数不能为空");
        }

        if (assignArticlesDto.CategoryId == Guid.Empty)
        {
            return ApiResponse<string>.Failure(400, "分类ID不能为空");
        }

        if (assignArticlesDto.ArticleIds == null || !assignArticlesDto.ArticleIds.Any())
        {
            return ApiResponse<string>.Failure(400, "文章ID不能为空");
        }

        var category = await _repository.GetByIdAsync(assignArticlesDto.CategoryId);

        if (category == null)
        {
            return ApiResponse<string>.Failure(5001, "分类不存在");
        }

        // 检查文章是否存在
        foreach (var articleId in assignArticlesDto.ArticleIds)
        {
            var article = await _articleRepository.GetByIdAsync(articleId);
            if (article == null)
            {
                return ApiResponse<string>.Failure(5003, "文章不存在");
            }
            category.AssignArticle(article);
        }

        await _repository.UpdateAsync(category);
        return ApiResponse<string>.Success("分配文章成功");
    }

    /// <summary>
    /// 从分类移除文章
    /// </summary>
    public async Task<dynamic> RemoveArticlesAsync(AssignArticlesDto assignArticlesDto)
    {
        // 参数验证
        if (assignArticlesDto == null)
        {
            return ApiResponse<string>.Failure(400, "参数不能为空");
        }

        if (assignArticlesDto.CategoryId == Guid.Empty)
        {
            return ApiResponse<string>.Failure(400, "分类ID不能为空");
        }

        if (assignArticlesDto.ArticleIds == null || !assignArticlesDto.ArticleIds.Any())
        {
            return ApiResponse<string>.Failure(400, "文章ID不能为空");
        }

        var category = await _repository.GetByIdAsync(assignArticlesDto.CategoryId);

        if (category == null)
        {
            return ApiResponse<string>.Failure(5001, "分类不存在");
        }

        // 移除文章
        foreach (var articleId in assignArticlesDto.ArticleIds)
        {
            var article = await _articleRepository.GetByIdAsync(articleId);
            if (article != null && article.CategoryId == assignArticlesDto.CategoryId)
            {
                category.RemoveArticle(article);
            }
        }

        await _repository.UpdateAsync(category);
        return ApiResponse<string>.Success("移除文章成功");
    }

    private ArticleCategoryDto MapToDto(AppArticleCategory entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }
        return new ArticleCategoryDto
        {
            Id = entity.Id,
            ArticleCategoryName = entity.ArticleCategoryName,
            Description = entity.Description,
            Sort = entity.Sort,
            ParentId = entity.ParentId,
            ParentName = entity.Parent?.ArticleCategoryName ?? string.Empty, // 修复：提供默认值
            IsActive = entity.IsActive,
            CreatedAt = entity.CreatedAt,
            UpdatedAt = entity.UpdatedAt,
            ArticleCount = entity.Articles?.Count ?? 0
        };
    }

    private ArticleCategoryDto BuildTree(AppArticleCategory category, List<AppArticleCategory> allCategories)
    {
        var dto = MapToDto(category);
        var children = allCategories.Where(x => x.ParentId == category.Id).ToList();
        dto.Children = children.Select(child => BuildTree(child, allCategories)).ToList();
        return dto;
    }
}